home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / gfx / show / gs_src_amiga.lha / gsmisc.c < prev    next >
C/C++ Source or Header  |  1996-01-18  |  16KB  |  498 lines

  1. /* Copyright (C) 1989, 1995 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsmisc.c */
  20. /* Miscellaneous utilities for Ghostscript library */
  21. #include "math_.h"
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gconfigv.h"        /* for USE_ASM */
  26. #include "gxfarith.h"
  27. #include "gxfixed.h"
  28.  
  29. /* Define private replacements for stdin, stdout, and stderr. */
  30. FILE *gs_stdin, *gs_stdout, *gs_stderr;
  31. /* Ghostscript writes debugging output to gs_debug_out. */
  32. /* We define gs_debug and gs_debug_out even if DEBUG isn't defined, */
  33. /* so that we can compile individual modules with DEBUG set. */
  34. char gs_debug[128];
  35. FILE *gs_debug_out;
  36.  
  37. /* Define eprintf_program_name and lprintf_file_and_line as procedures */
  38. /* so one can set breakpoints on them. */
  39. void
  40. eprintf_program_name(FILE *f, const char *program_name)
  41. {    fprintf(f, "%s: ", program_name);
  42. }
  43. void
  44. lprintf_file_and_line(FILE *f, const char *file, int line)
  45. {    fprintf(f, "%s(%d): ", file, line);
  46. }
  47.  
  48. /* Log an error return.  We always include this, in case other */
  49. /* modules were compiled with DEBUG set. */
  50. #undef gs_log_error        /* in case DEBUG isn't set */
  51. int
  52. gs_log_error(int err, const char _ds *file, int line)
  53. {    if ( gs_log_errors )
  54.       { if ( file == NULL )
  55.           dprintf1("Returning error %d.\n", err);
  56.         else
  57.           dprintf3("%s(%d): Returning error %d.\n",
  58.                (char *)file, line, err);
  59.       }
  60.     return err;
  61. }
  62.  
  63. /* ------ Substitutes for missing C library functions ------ */
  64.  
  65. #ifdef memory__need_memmove        /* see memory_.h */
  66. /* Copy bytes like memcpy, guaranteed to handle overlap correctly. */
  67. /* ANSI C defines the returned value as being the src argument, */
  68. /* but with the const restriction removed! */
  69. void *
  70. gs_memmove(void *dest, const void *src, size_t len)
  71. {    if ( !len )
  72.         return (void *)src;
  73. #define bdest ((byte *)dest)
  74. #define bsrc ((const byte *)src)
  75.     /* We use len-1 for comparisons because adding len */
  76.     /* might produce an offset overflow on segmented systems. */
  77.     if ( ptr_le(bdest, bsrc) )
  78.       {    register byte *end = bdest + (len - 1);
  79.         if ( ptr_le(bsrc, end) )
  80.           {    /* Source overlaps destination from above. */
  81.             register const byte *from = bsrc;
  82.             register byte *to = bdest;
  83.             for ( ; ; )
  84.               {    *to = *from;
  85.                 if ( to >= end )    /* faster than = */
  86.                   return (void *)src;
  87.                 to++; from++;
  88.               }
  89.           }
  90.       }
  91.     else
  92.       {    register const byte *from = bsrc + (len - 1);
  93.         if ( ptr_le(bdest, from) )
  94.           {    /* Source overlaps destination from below. */
  95.             register const byte *end = bsrc;
  96.             register byte *to = bdest + (len - 1);
  97.             for ( ; ; )
  98.               {    *to = *from;
  99.                 if ( from <= end )    /* faster than = */
  100.                   return (void *)src;
  101.                 to--; from--;
  102.               }
  103.           }
  104.       }
  105. #undef bdest
  106. #undef bsrc
  107.     /* No overlap, it's safe to use memcpy. */
  108.     memcpy(dest, src, len);
  109.     return (void *)src;
  110. }
  111. #endif
  112.  
  113. #ifdef memory__need_memchr        /* see memory_.h */
  114. /* ch should obviously be char rather than int, */
  115. /* but the ANSI standard declaration uses int. */
  116. const char *
  117. gs_memchr(const char *ptr, int ch, size_t len)
  118. {    if ( len > 0 )
  119.     {    register const char *p = ptr;
  120.         register uint count = len;
  121.         do { if ( *p == (char)ch ) return p; p++; } while ( --count );
  122.     }
  123.     return 0;
  124. }
  125. #endif
  126.  
  127. #ifdef memory__need_memset        /* see memory_.h */
  128. /* ch should obviously be char rather than int, */
  129. /* but the ANSI standard declaration uses int. */
  130. void *
  131. gs_memset(void *dest, register int ch, size_t len)
  132. {    if ( ch == 0 )
  133.         bzero(dest, len);
  134.     else if ( len > 0 )
  135.     {    register char *p = dest;
  136.         register uint count = len;
  137.         do { *p++ = (char)ch; } while ( --count );
  138.     }
  139.     return dest;
  140. }
  141. #endif
  142.  
  143. /* ------ Debugging support ------ */
  144.  
  145. /* Dump a region of memory. */
  146. void
  147. debug_dump_bytes(const byte *from, const byte *to, const char *msg)
  148. {    const byte *p = from;
  149.     if ( from < to && msg )
  150.         dprintf1("%s:\n", msg);
  151.     while ( p != to )
  152.        {    const byte *q = min(p + 16, to);
  153.         dprintf1("0x%lx:", (ulong)p);
  154.         while ( p != q ) dprintf1(" %02x", *p++);
  155.         dputc('\n');
  156.        }
  157. }
  158.  
  159. /* Dump a bitmap. */
  160. void
  161. debug_dump_bitmap(const byte *bits, uint raster, uint height, const char *msg)
  162. {    uint y;
  163.     const byte *data = bits;
  164.     for ( y = 0; y < height; ++y, data += raster )
  165.         debug_dump_bytes(data, data + raster, (y == 0 ? msg : NULL));
  166. }
  167.  
  168. /* Print a string. */
  169. void
  170. debug_print_string(const byte *chrs, uint len)
  171. {    uint i;
  172.     for ( i = 0; i < len; i++ )
  173.       dputc(chrs[i]);
  174.     fflush(dstderr);
  175. }
  176.  
  177. /* ------ Arithmetic ------ */
  178.  
  179. /* Compute the GCD of two integers. */
  180. int
  181. igcd(int x, int y)
  182. {    int c = x, d = y;
  183.     if ( c < 0 ) c = -c;
  184.     if ( d < 0 ) d = -d;
  185.     while ( c != 0 && d != 0 )
  186.       if ( c > d ) c %= d;
  187.       else d %= c;
  188.     return d + c;        /* at most one is non-zero */
  189. }
  190.  
  191. #if defined(set_fmul2fixed_vars) && !USE_ASM
  192.  
  193. /*
  194.  * Floating multiply with fixed result, for avoiding floating point in
  195.  * common coordinate transformations.  Assumes IEEE representation,
  196.  * 16-bit short, 32-bit long.  Optimized for the case where the first
  197.  * operand has no more than 16 mantissa bits, e.g., where it is a user space
  198.  * coordinate (which are often integers).
  199.  *
  200.  * The assembly language version of this code is actually faster than
  201.  * the FPU, if the code is compiled with FPU_TYPE=0 (which requires taking
  202.  * a trap on every FPU operation).  If there is no FPU, the assembly
  203.  * language version of this code is over 10 times as fast as the emulated FPU.
  204.  */
  205. /* Some of the following code has been tweaked for the Borland 16-bit */
  206. /* compiler.  The tweaks do not change the algorithms. */
  207. #if arch_ints_are_short && !defined(FOR80386)
  208. #  define SHORT_ARITH
  209. #endif
  210. int
  211. set_fmul2fixed_(fixed *pr, long /*float*/ a, long /*float*/ b)
  212. {
  213. #ifdef SHORT_ARITH
  214. #  define long_rsh8_ushort(x)\
  215.     (((ushort)(x) >> 8) | ((ushort)((ulong)(x) >> 16) << 8))
  216. #  define utemp ushort
  217. #else
  218. #  define long_rsh8_ushort(x) ((ushort)((x) >> 8))
  219. #  define utemp ulong
  220. #endif
  221.     /* utemp may be either ushort or ulong.  This is OK because */
  222.     /* we only use ma and mb in multiplications involving */
  223.     /* a long or ulong operand. */
  224.     utemp ma = long_rsh8_ushort(a) | 0x8000;
  225.     utemp mb = long_rsh8_ushort(b) | 0x8000;
  226.     int e = 260 + _fixed_shift - ((
  227.         (((uint)((ulong)a >> 16)) & 0x7f80) +
  228.         (((uint)((ulong)b >> 16)) & 0x7f80)
  229.       ) >> 7);
  230.     ulong p1 = ma * (b & 0xff);
  231.     ulong p = (ulong)ma * mb;
  232. #define p_bits (sizeof(p) * 8)
  233.  
  234.     if ( (byte)a )        /* >16 mantissa bits */
  235.     {    ulong p2 = (a & 0xff) * mb;
  236.         p += ((((uint)(byte)a * (uint)(byte)b) >> 8) + p1 + p2) >> 8;
  237.     }
  238.     else
  239.         p += p1 >> 8;
  240.     if ( (uint)e < p_bits )        /* e = -1 is possible */
  241.         p >>= e;
  242.     else if ( e >= p_bits )        /* also detects a=0 or b=0 */
  243.       {    *pr = fixed_0;
  244.         return 0;
  245.       }
  246.     else if ( e >= -(p_bits - 1) || p >= 1L << (p_bits - 1 + e) )
  247.         return_error(gs_error_limitcheck);
  248.     else
  249.         p <<= -e;
  250.     *pr = ((a ^ b) < 0 ? -p : p);
  251.     return 0;
  252. }
  253. int
  254. set_dfmul2fixed_(fixed *pr, ulong /*double lo*/ xalo, long /*float*/ b, long /*double hi*/ xahi)
  255. {
  256. #ifdef SHORT_ARITH
  257. #  define long_lsh3(x) ((((x) << 1) << 1) << 1)
  258. #  define long_rsh(x,ng16) ((uint)((x) >> 16) >> (ng16 - 16))
  259. #else
  260. #  define long_lsh3(x) ((x) << 3)
  261. #  define long_rsh(x,ng16) ((x) >> ng16)
  262. #endif
  263.     return set_fmul2fixed_(pr,
  264.                    (xahi & 0xc0000000) +
  265.                     (long_lsh3(xahi) & 0x3ffffff8) +
  266.                     long_rsh(xalo, 29),
  267.                    b);
  268. }
  269.  
  270. #endif
  271.  
  272. /* Trace calls on sqrt when debugging. */
  273. #undef sqrt
  274. #ifndef AMIGA
  275. extern double sqrt(P1(double));
  276. #endif
  277. double
  278. gs_sqrt(double x, const char *file, int line)
  279. {    if ( gs_debug_c('~') )
  280.       {    fprintf(stdout, "[~]sqrt(%g) at %s:%d\n",
  281.             x, (const char *)file, line);
  282.         fflush(stdout);
  283.       }
  284.     return sqrt(x);
  285. }
  286.  
  287. /*
  288.  * Define sine and cosine functions that take angles in degrees rather than
  289.  * radians, and that are implemented efficiently on machines with slow
  290.  * (or no) floating point.
  291.  */
  292. #if USE_FPU < 0            /****** maybe should be <= 0 ? ******/
  293.  
  294. #define sin0 0.00000000000000000
  295. #define sin1 0.01745240643728351
  296. #define sin2 0.03489949670250097
  297. #define sin3 0.05233595624294383
  298. #define sin4 0.06975647374412530
  299. #define sin5 0.08715574274765817
  300. #define sin6 0.10452846326765346
  301. #define sin7 0.12186934340514748
  302. #define sin8 0.13917310096006544
  303. #define sin9 0.15643446504023087
  304. #define sin10 0.17364817766693033
  305. #define sin11 0.19080899537654480
  306. #define sin12 0.20791169081775931
  307. #define sin13 0.22495105434386498
  308. #define sin14 0.24192189559966773
  309. #define sin15 0.25881904510252074
  310. #define sin16 0.27563735581699916
  311. #define sin17 0.29237170472273671
  312. #define sin18 0.30901699437494740
  313. #define sin19 0.32556815445715670
  314. #define sin20 0.34202014332566871
  315. #define sin21 0.35836794954530027
  316. #define sin22 0.37460659341591201
  317. #define sin23 0.39073112848927377
  318. #define sin24 0.40673664307580015
  319. #define sin25 0.42261826174069944
  320. #define sin26 0.43837114678907740
  321. #define sin27 0.45399049973954675
  322. #define sin28 0.46947156278589081
  323. #define sin29 0.48480962024633706
  324. #define sin30 0.50000000000000000
  325. #define sin31 0.51503807491005416
  326. #define sin32 0.52991926423320490
  327. #define sin33 0.54463903501502708
  328. #define sin34 0.55919290347074679
  329. #define sin35 0.57357643635104605
  330. #define sin36 0.58778525229247314
  331. #define sin37 0.60181502315204827
  332. #define sin38 0.61566147532565829
  333. #define sin39 0.62932039104983739
  334. #define sin40 0.64278760968653925
  335. #define sin41 0.65605902899050728
  336. #define sin42 0.66913060635885824
  337. #define sin43 0.68199836006249848
  338. #define sin44 0.69465837045899725
  339. #define sin45 0.70710678118654746
  340. #define sin46 0.71933980033865108
  341. #define sin47 0.73135370161917046
  342. #define sin48 0.74314482547739413
  343. #define sin49 0.75470958022277201
  344. #define sin50 0.76604444311897801
  345. #define sin51 0.77714596145697090
  346. #define sin52 0.78801075360672190
  347. #define sin53 0.79863551004729283
  348. #define sin54 0.80901699437494745
  349. #define sin55 0.81915204428899180
  350. #define sin56 0.82903757255504174
  351. #define sin57 0.83867056794542394
  352. #define sin58 0.84804809615642596
  353. #define sin59 0.85716730070211222
  354. #define sin60 0.86602540378443860
  355. #define sin61 0.87461970713939574
  356. #define sin62 0.88294759285892688
  357. #define sin63 0.89100652418836779
  358. #define sin64 0.89879404629916704
  359. #define sin65 0.90630778703664994
  360. #define sin66 0.91354545764260087
  361. #define sin67 0.92050485345244037
  362. #define sin68 0.92718385456678731
  363. #define sin69 0.93358042649720174
  364. #define sin70 0.93969262078590832
  365. #define sin71 0.94551857559931674
  366. #define sin72 0.95105651629515353
  367. #define sin73 0.95630475596303544
  368. #define sin74 0.96126169593831889
  369. #define sin75 0.96592582628906831
  370. #define sin76 0.97029572627599647
  371. #define sin77 0.97437006478523525
  372. #define sin78 0.97814760073380558
  373. #define sin79 0.98162718344766398
  374. #define sin80 0.98480775301220802
  375. #define sin81 0.98768834059513777
  376. #define sin82 0.99026806874157036
  377. #define sin83 0.99254615164132198
  378. #define sin84 0.99452189536827329
  379. #define sin85 0.99619469809174555
  380. #define sin86 0.99756405025982420
  381. #define sin87 0.99862953475457383
  382. #define sin88 0.99939082701909576
  383. #define sin89 0.99984769515639127
  384. #define sin90 1.00000000000000000
  385.  
  386. private const double sin_table[361] = {
  387.   sin0,
  388.   sin1, sin2, sin3, sin4, sin5, sin6, sin7, sin8, sin9, sin10,
  389.   sin11, sin12, sin13, sin14, sin15, sin16, sin17, sin18, sin19, sin20,
  390.   sin21, sin22, sin23, sin24, sin25, sin26, sin27, sin28, sin29, sin30,
  391.   sin31, sin32, sin33, sin34, sin35, sin36, sin37, sin38, sin39, sin40,
  392.   sin41, sin42, sin43, sin44, sin45, sin46, sin47, sin48, sin49, sin50,
  393.   sin51, sin52, sin53, sin54, sin55, sin56, sin57, sin58, sin59, sin60,
  394.   sin61, sin62, sin63, sin64, sin65, sin66, sin67, sin68, sin69, sin70,
  395.   sin71, sin72, sin73, sin74, sin75, sin76, sin77, sin78, sin79, sin80,
  396.   sin81, sin82, sin83, sin84, sin85, sin86, sin87, sin88, sin89, sin90,
  397.   sin89, sin88, sin87, sin86, sin85, sin84, sin83, sin82, sin81, sin80,
  398.   sin79, sin78, sin77, sin76, sin75, sin74, sin73, sin72, sin71, sin70,
  399.   sin69, sin68, sin67, sin66, sin65, sin64, sin63, sin62, sin61, sin60,
  400.   sin59, sin58, sin57, sin56, sin55, sin54, sin53, sin52, sin51, sin50,
  401.   sin49, sin48, sin47, sin46, sin45, sin44, sin43, sin42, sin41, sin40,
  402.   sin39, sin38, sin37, sin36, sin35, sin34, sin33, sin32, sin31, sin30,
  403.   sin29, sin28, sin27, sin26, sin25, sin24, sin23, sin22, sin21, sin20,
  404.   sin19, sin18, sin17, sin16, sin15, sin14, sin13, sin12, sin11, sin10,
  405.   sin9, sin8, sin7, sin6, sin5, sin4, sin3, sin2, sin1, sin0,
  406.   -sin1, -sin2, -sin3, -sin4, -sin5, -sin6, -sin7, -sin8, -sin9, -sin10,
  407. -sin11, -sin12, -sin13, -sin14, -sin15, -sin16, -sin17, -sin18, -sin19, -sin20,
  408. -sin21, -sin22, -sin23, -sin24, -sin25, -sin26, -sin27, -sin28, -sin29, -sin30,
  409. -sin31, -sin32, -sin33, -sin34, -sin35, -sin36, -sin37, -sin38, -sin39, -sin40,
  410. -sin41, -sin42, -sin43, -sin44, -sin45, -sin46, -sin47, -sin48, -sin49, -sin50,
  411. -sin51, -sin52, -sin53, -sin54, -sin55, -sin56, -sin57, -sin58, -sin59, -sin60,
  412. -sin61, -sin62, -sin63, -sin64, -sin65, -sin66, -sin67, -sin68, -sin69, -sin70,
  413. -sin71, -sin72, -sin73, -sin74, -sin75, -sin76, -sin77, -sin78, -sin79, -sin80,
  414. -sin81, -sin82, -sin83, -sin84, -sin85, -sin86, -sin87, -sin88, -sin89, -sin90,
  415. -sin89, -sin88, -sin87, -sin86, -sin85, -sin84, -sin83, -sin82, -sin81, -sin80,
  416. -sin79, -sin78, -sin77, -sin76, -sin75, -sin74, -sin73, -sin72, -sin71, -sin70,
  417. -sin69, -sin68, -sin67, -sin66, -sin65, -sin64, -sin63, -sin62, -sin61, -sin60,
  418. -sin59, -sin58, -sin57, -sin56, -sin55, -sin54, -sin53, -sin52, -sin51, -sin50,
  419. -sin49, -sin48, -sin47, -sin46, -sin45, -sin44, -sin43, -sin42, -sin41, -sin40,
  420. -sin39, -sin38, -sin37, -sin36, -sin35, -sin34, -sin33, -sin32, -sin31, -sin30,
  421. -sin29, -sin28, -sin27, -sin26, -sin25, -sin24, -sin23, -sin22, -sin21, -sin20,
  422. -sin19, -sin18, -sin17, -sin16, -sin15, -sin14, -sin13, -sin12, -sin11, -sin10,
  423.   -sin9, -sin8, -sin7, -sin6, -sin5, -sin4, -sin3, -sin2, -sin1, -sin0
  424. };
  425.  
  426. double
  427. gs_sin_degrees(double ang)
  428. {    int ipart;
  429.     if ( is_fneg(ang) )
  430.       ang = 180 - ang;
  431.     ipart = (int)ang;
  432.     if ( ipart >= 360 )
  433.       { int arem = ipart % 360;
  434.         ang -= (ipart - arem);
  435.         ipart = arem;
  436.       }
  437.     return
  438.       (ang == ipart ? sin_table[ipart] :
  439.        sin_table[ipart] + (sin_table[ipart+1] - sin_table[ipart]) *
  440.          (ang - ipart));
  441. }
  442.  
  443. double
  444. gs_cos_degrees(double ang)
  445. {    int ipart;
  446.     if ( is_fneg(ang) )
  447.       ang = 90 - ang;
  448.     else
  449.       ang += 90;
  450.     ipart = (int)ang;
  451.     if ( ipart >= 360 )
  452.       { int arem = ipart % 360;
  453.         ang -= (ipart - arem);
  454.         ipart = arem;
  455.       }
  456.     return
  457.       (ang == ipart ? sin_table[ipart] :
  458.        sin_table[ipart] + (sin_table[ipart+1] - sin_table[ipart]) *
  459.          (ang - ipart));
  460. }
  461.  
  462. void
  463. gs_sincos_degrees(double ang, gs_sincos_t *psincos)
  464. {    psincos->sin = gs_sin_degrees(ang);
  465.     psincos->cos = gs_cos_degrees(ang);
  466. }
  467.  
  468. #else                /* we have floating point */
  469.  
  470. double
  471. gs_sin_degrees(double ang)
  472. {    return sin(ang * (M_PI / 180));
  473. }
  474.  
  475. double
  476. gs_cos_degrees(double ang)
  477. {    return cos(ang * (M_PI / 180));
  478. }
  479.  
  480. void
  481. gs_sincos_degrees(double ang, gs_sincos_t *psincos)
  482. {    int quads;
  483.     if ( ang >= -360 && ang <= 360 &&
  484.          ang == (quads = (int)ang / 90) * 90
  485.        )
  486.     {    static const int isincos[5] = { 0, 1, 0, -1, 0 };
  487.         quads &= 3;
  488.         psincos->sin = isincos[quads];
  489.         psincos->cos = isincos[quads + 1];
  490.     }
  491.     else
  492.     {    psincos->sin = gs_sin_degrees(ang);
  493.         psincos->cos = gs_cos_degrees(ang);
  494.     }
  495. }
  496.  
  497. #endif                /* USE_FPU */
  498.